﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Markup;


namespace UBCon.Ribbon
{
    [ContentProperty("Items")]
    [TemplatePart(Name = PART_TabControlSelectorName, Type = typeof(TabControlSelector))]
    public class TabControl : Control
    {
        //------------------------------------------------------
        //
        //  Constructors
        //
        //------------------------------------------------------
        #region Constructors

        /// <summary>
        /// Default static constructor
        /// </summary>
        static TabControl()
        {
            Type ownerType = typeof(TabControl);
            DefaultStyleKeyProperty.OverrideMetadata(ownerType, new FrameworkPropertyMetadata(ownerType));
        }

        /// <summary>
        /// Initializes a new instance of UBCon.Ribbon.TabControl class.
        /// </summary>
        public TabControl()
        {
            Items = new ObservableCollection<TabItem>();
            Items.CollectionChanged += OnItemsCollectionChanged;
            Loaded += OnTabControlLoaded;
            

        }
        #endregion

        //------------------------------------------------------
        //
        //  Properties
        //
        //------------------------------------------------------
        #region Properties

        /// <summary>
        /// Gets the collection of items used to generate UBCon.Ribbon.TabControl.
        /// </summary>
        public ObservableCollection<TabItem> Items
        {
            get { return (ObservableCollection<TabItem>)GetValue(ItemsProperty); }
            set { SetValue(ItemsProperty, value); }
        }

        /// <summary>
        /// Identifies UBCon.Ribbon.TabControl.Items dependeny property.
        /// </summary>
        public static readonly DependencyProperty ItemsProperty =
            DependencyProperty.Register("Items", typeof(ObservableCollection<TabItem>), typeof(TabControl), new PropertyMetadata((ObservableCollection<TabItem>)null));

        /// <summary>
        /// Gets or sets a boolean value tha indicates whether UBCon.Ribbon.TabControl has items.
        /// </summary>
        public bool HasItems
        {
            get { return (bool)GetValue(HasItemsProperty); }
            internal set { SetValue(HasItemsPropertyKey, value); }
        }

        /// <summary>
        /// Identifies UBCon.Ribbon.TabControl.HasItems dependeny property.
        /// </summary>
        internal static readonly DependencyPropertyKey HasItemsPropertyKey =
            DependencyProperty.RegisterReadOnly("HasItems", typeof(bool), typeof(TabControl), new PropertyMetadata(false));

        internal static readonly DependencyProperty HasItemsProperty = HasItemsPropertyKey.DependencyProperty;

        #endregion

        //------------------------------------------------------
        //
        //  Depenency Property Changed Callbacks
        //
        //------------------------------------------------------
        #region Depenency Property Changed Callbacks
        #endregion

        //------------------------------------------------------
        //
        //  Overrides
        //
        //------------------------------------------------------
        #region Overrides

        /// <summary>
        /// Invoked whenever application code or internal processes call System.Windows.FrameworkElement.OnApplyTemplate().
        /// </summary>
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            if (_collectionView != null) 
            {
                _collectionView.CollectionChanged -= OnTabControlSelectorItemsChanged;
            }
            _selector = GetTemplateChild(PART_TabControlSelectorName) as TabControlSelector;
            if (_selector == null)
            {
                throw new NullReferenceException("TabControlSelector control cannot be null. Review the template");
            }
            _collectionView = CollectionViewSource.GetDefaultView(_selector.Items);
            if (_collectionView != null)
            {
                _collectionView.CollectionChanged += OnTabControlSelectorItemsChanged;
            }

            _selector._wrapperControl = this;
        }

        #endregion

        //------------------------------------------------------
        //
        //  Virual members
        //
        //------------------------------------------------------
        #region Virual members

        #endregion

        //------------------------------------------------------
        //
        //  Public Methods
        //
        //------------------------------------------------------
        #region Public Methods

           
      
        #endregion

        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------
        #region Internal Methods
        #endregion

        //------------------------------------------------------
        //
        //  Private Methods
        //
        //------------------------------------------------------
        #region Private Methods


        #endregion

        //------------------------------------------------------
        //
        //  Event Handlers
        //
        //------------------------------------------------------
        #region Event Handlers

        /// <summary>
        /// Invoked when Loaded event is fired which means the element is laid out, 
        /// rendered and ready for interaction
        /// </summary>
        private void OnTabControlLoaded(object sender, RoutedEventArgs e)
        {
            Loaded -= OnTabControlLoaded;

            if (Items.Count > 0)
            {
                TabItem tabItem = Items[Items.Count - 1];
                tabItem.SetValue(TabItem.IsLastItemProperty, true);

                if (_selector != null && _selector.SelectedIndex < 0)
                {
                    _selector.SetValue(Selector.SelectedIndexProperty, 0);
                }
            }

            
        }

        /// <summary>
        /// Invoked when an item is added, removed, changed, moved, or the entire list is refreshed
        /// </summary>
        private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (_selector != null && IsLoaded)
            {
                
                switch (e.Action)
                {
                    case NotifyCollectionChangedAction.Add:

                        foreach (TabItem item in e.NewItems)
                        {
                            _selector.Items.Add(item);
                        }
                        
                        break;
                    case NotifyCollectionChangedAction.Remove:

                        foreach (TabItem item in e.OldItems)
                        {
                            _selector.Items.Remove(item);
                        }
                        break;
                        
                      
                }
                TabItem tabItem = (from t in Items where (t as TabItem).IsLastItem select t).FirstOrDefault();
                if (tabItem != null)
                {
                    tabItem.SetValue(TabItem.IsLastItemProperty, false);
                }
                if (Items.Count > 0)
                {
                    tabItem = Items[Items.Count - 1];
                    tabItem.SetValue(TabItem.IsLastItemProperty, true);
                }
            }
        }

        /// <summary>
        /// Invoked when an item is added, removed, changed, moved, or the entire list is refreshed
        /// </summary>
        private void OnTabControlSelectorItemsChanged(object sender, NotifyCollectionChangedEventArgs e) 
        {
            bool hasItems = _selector.Items.Count > 0;

            if (_selector.SelectedIndex < 0&&hasItems) 
            {
                _selector.SetCurrentValue(System.Windows.Controls.Primitives.Selector.SelectedIndexProperty, 0);
            }
            SetValue(HasItemsPropertyKey, hasItems);
        }
        #endregion

        //------------------------------------------------------
        //
        //  Fields
        //
        //------------------------------------------------------
        #region Fields
        private const string PART_TabControlSelectorName = "PART_TabControlSelector";

        internal TabControlSelector _selector;
        private ICollectionView _collectionView;
        #endregion

        //------------------------------------------------------
        //
        //  Events
        //
        //------------------------------------------------------
        #region Events
        #endregion

        //------------------------------------------------------
        //
        //  Commands
        //
        //------------------------------------------------------
        #region Commands
        #endregion

    }

}
